package edu.ncut.vod.smart.jrsoft.chart;

import java.awt.Color;
import java.awt.Font;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PiePlot3D;
import org.jfree.chart.urls.StandardPieURLGenerator;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.util.Rotation;
import javax.servlet.http.*;

public class DrawPie {

    private String title = ""; // 图片标题
    private Color bgcolor = null; // 图片背景颜色
    private float foreAlpha = 0.5F; // 饼图透明度值 0---1
    private int labelFontSize = 10; // 分类字体大小
    private double factor = 0.2; // 3D饼图的Z轴高度（0.0～1.0）
    private int width = 600; // 要生成的图片的宽度
    private int height = 350; // 要生成的图片的高度
    private String fileName = ""; // 图片名称(可以加路经)
    /* public class DefaultPieDatas etextends AbstractDataset implements PieDataset, 
     * java.lang.Cloneable, org.jfree.util.PublicCloneable, java.io.Serializable 
     * A default implementation of the PieDataset interface. */
    private DefaultPieDataset dataset = null; // 显示图片需用的数据集
    private FileOutputStream fosJpg = null; // 生成图片是用到的输出流
    private static DrawPie instance = null;
    
    /**
     * constructor without parameter
     */
    public DrawPie() {
        
    }

    /**
     * 单态模式生成类对象
     * @return 该类的一个对象
     */
    public static synchronized DrawPie getInstance() {
        if (instance == null)
            instance = new DrawPie();
        return instance;
    }

    /**
     * 改变图表标题
     * @param str 图表标题
     */
    public void setTitle(String str) {
        this.title = str;
    }

    /**
     * 改变背景颜色
     * @param color 背景颜色
     */
    public void setBgcolor(int red, int green, int blue) {
        this.bgcolor = new Color(red, green, blue);
    }

    /**
     * 改变背景颜色
     * @param color 背景颜色
     */
    public void setBgcolor(Color color) {
        this.bgcolor = color;
    }

    /**
     * 改变背景颜色
     * @param str 背景颜色描述 比如:BLACK black blue Blue 等
     */
    public void setBgColor(String str) {
        this.bgcolor = ChangeColor.getColor(str);
    }

    /**
     * 设置饼图透明度
     * @param value
     */
    public void setForeAlpha(float value) {
        this.foreAlpha = value;
    }

    /**
     * 改变图片宽度
     * @param width 图片宽度
     */
    public void setWidth(int width) {
        this.width = width;
    }

    /**
     * 改变图片高度
     * @param height 图片高度
     */
    public void setHeight(int height) {
        this.height = height;
    }

    /**
     * 改变分类标签字体
     * @param i 分类标签字体大小
     */
    public void setLabelFontSize(int i) {
        this.labelFontSize = i;
    }

    /**
     * 改变饼图的Z轴
     * @param dbl 饼图的Z轴高度
     */
    public void setFactor(double dbl) {
        this.factor = dbl;
    }

    /**
     * 改变文件名称
     * @param str 文件名称
     */
    private void setFileName(String str) {
        this.fileName = str;
    }

    /**
     * 初始化参数
     */
    public void init() {
        setTitle("饼图标题:关于被点播的视频的信息");
        setWidth(600);
        setHeight(350);
        setBgcolor(Color.white);
        setForeAlpha(0.5F);
        setFileName("d:\\temp.jpg");
    }

    /**
     * 添加要进行画柱状图的数据
     * @param value 单元值
     * @param name 单元项名称
     */
    public void addData(String name, double value) {
        if (this.dataset != null) {
            /*
             * public void setValue(java.lang.Comparable key,double value):Sets the data value for 
             * a key and sends a DatasetChangeEvent to all registered listeners. 
             */
            this.dataset.setValue(name, value);
        } else {
            init();
            this.dataset = new DefaultPieDataset();
            this.dataset.setValue(name, value);
        }
    }

    /**
     * 按照文件路径保存图片
     * @param fileName 要保存的文件名称 文件名称为（使用路径为）: d:\\web\test.jpg
     * @return true 成功 false 失败
     */
    public boolean saveAbs(String fileName) {
        if (!fileName.equals("temp.jpg")) {
            this.setFileName(fileName);
        }
        if (dataset == null) {
            return false;
        } else {
            /*
             * public class JFreeChart extends java.lang.Object implements org.jfree.ui.Drawable, 
             * TitleChangeListener, PlotChangeListener, java.io.Serializable, java.lang.Cloneable:
             * A chart class implemented using the Java 2D APIs. The current version supports bar 
             * charts, line charts, pie charts and xy plots (including time series data). 
             * 
             * public abstract class ChartFactory extends java.lang.Object:A collection of utility 
             * methods for creating some standard charts with JFreeChart. 
             * 
             * public static JFreeChart createPieChart3D(java.lang.String title,PieDataset dataset,
             * boolean legend,boolean tooltips,boolean urls):
             * Creates a 3D pie chart using the specified dataset. The chart object returned by 
             * this method uses a PiePlot3D instance as the plot. 
             */
            JFreeChart piechart = ChartFactory.createPieChart3D(this.title,
                    this.dataset, true, false, false);
            /*
             * public void setBackgroundPaint(java.awt.Paint paint):
             * Sets the paint used to fill the chart background and sends a ChartChangeEvent to 
             * all registered listeners. 
             */
            piechart.setBackgroundPaint(this.bgcolor); // 设置背景颜色
            /*
             * public class PiePlot extends Plot implements java.lang.Cloneable, java.io.Serializable:
             * A plot that displays data in the form of a pie chart, using data from any class that 
             * implements the PieDataset interface. 
             * 
             * public Plot getPlot():Returns the plot for the chart. The plot is a class 
             * responsible for coordinating the visual representation of the data, including 
             * the axes (if any). 
             */
            PiePlot pieplot = (PiePlot) piechart.getPlot();
            pieplot.setLabelFont(new Font("black", Font.BOLD,
                    this.labelFontSize));// 分类标签字体
            PiePlot3D pieplot3d = (PiePlot3D) piechart.getPlot();
            pieplot3d.setDepthFactor(factor);// 3D饼图的Z轴高度
            pieplot3d.setStartAngle(290D);
            pieplot3d.setDirection(Rotation.CLOCKWISE);
            pieplot3d.setForegroundAlpha(this.foreAlpha);
            pieplot3d.setNoDataMessage("No data to display");
            try {
                fosJpg = new FileOutputStream(fileName);
                ChartUtilities.writeChartAsJPEG(fosJpg, 100, piechart,
                        this.width, this.height, null);

            } catch (Exception e) {
            } finally {
                try {
                    fosJpg.close();
                } catch (Exception e) {
                }
            }
            return true;
        }
    }

    /**
     * 按照文件路径保存图片及地图文件
     * @param fileName 要保存的文件名称 文件名称为（使用路径为）: d:\\web\test.jpg
     * @return true 成功 false 失败
     */
    public boolean saveMap(String imgName, String mapName, String url) {
        PrintWriter w = null;
        FileOutputStream fosCri = null;
        ChartRenderingInfo info = new ChartRenderingInfo();

        if (!fileName.equals("temp.jpg")) {
            this.setFileName(fileName);
        }
        if (dataset == null) {
            return false;
        } else {
            JFreeChart piechart = ChartFactory.createPieChart3D(this.title,
                    this.dataset, true, false, false);
            piechart.setBackgroundPaint(this.bgcolor); // 设置背景颜色

            PiePlot pieplot = (PiePlot) piechart.getPlot();
            pieplot.setLabelFont(new Font("black", Font.BOLD,
                    this.labelFontSize));// 分类标签字体
            PiePlot3D pieplot3d = (PiePlot3D) piechart.getPlot();
            pieplot3d.setDepthFactor(factor);// 3D饼图的Z轴高度
            pieplot3d.setStartAngle(290D);
            pieplot3d.setDirection(Rotation.CLOCKWISE);
            pieplot3d.setForegroundAlpha(this.foreAlpha);
            pieplot3d.setNoDataMessage("No data to display");
            pieplot3d.setURLGenerator(new StandardPieURLGenerator(url));
            try {
                fosJpg = new FileOutputStream(imgName);
                ChartUtilities.writeChartAsJPEG(fosJpg, 100, piechart,
                        this.width, this.height, info);
                fosCri = new FileOutputStream(mapName);
                w = new PrintWriter(fosCri);
                ChartUtilities.writeImageMap(w, "testName", info, true);
                w.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    w.close();
                } catch (Exception e) {
                }
                try {
                    fosCri.close();
                } catch (Exception e) {
                }
                try {
                    fosJpg.close();
                } catch (Exception e) {
                }
            }
            return true;
        }
    }

    /**
     * 根据网站的根站点路径保存图片
     * @param request 在jsp页面中的request对象 用于获取文件路径
     * @param fileName 保存文件名称 文件名称必须使用站点的绝对路径 如 : “/admin/test.jpg"
     * @return true 成功 false 失败
     */
    public boolean saveWebFile(HttpServletRequest request, String fileName) {
        if (!fileName.equals("")) {
            this.setFileName(fileName);
        }
        fileName = request.getRealPath("") + fileName;
        if (dataset == null) {
            return false;
        } else {
            JFreeChart piechart = ChartFactory.createPieChart3D(this.title,
                    this.dataset, true, false, false);
            piechart.setBackgroundPaint(this.bgcolor); // 设置背景颜色
            PiePlot3D pieplot3d = (PiePlot3D) piechart.getPlot();
            pieplot3d.setStartAngle(290D);
            pieplot3d.setDirection(Rotation.CLOCKWISE);
            pieplot3d.setForegroundAlpha(this.foreAlpha);
            pieplot3d.setNoDataMessage("No data to display");
            try {
                fosJpg = new FileOutputStream(fileName);
                ChartUtilities.writeChartAsJPEG(fosJpg, 100, piechart,
                        this.width, this.height, null);
            } catch (Exception e) {
            } finally {

                try {
                    fosJpg.close();
                } catch (Exception e) {
                }
            }
            return true;
        }
    }

    public static void main(String[] args) {
        // 1.��ɻ���ͼ�������
        DrawPie test = DrawPie.getInstance();
        // 2.��ӻ�ͼ����ݼ�
        test.addData("����", 43.00);
        test.addData("����", 40.34);
        test.addData("����", 17.23);
        test.addData("΢��", 32.43);
        test.addData("��Ϊ", 45.23);
        test.addData("IBM", 22.34);
        // 3.����ͼƬ����
        test.init();
        test.setBgcolor(Color.white);
        test.setTitle("��ͼ����");
        test.setWidth(800);
        test.setHeight(450);
        test.setLabelFontSize(10);
        test.setFactor(0.2);
        // 4.����ͼƬ
        test.saveAbs("E:\\pie.jpg");
        // 5.ͬʱ����ͼƬ�ļ��͵�ͼ�ļ�
        // test.saveMap("E:\\pie.jpg","E:\\pie.map","http://localhost:8080/test/MyJsp.jsp");
    }
}
